/**
 * @file iec104_protocol_bridge.c
 * @brief IEC 104协议桥接模块实现
 * @details 实现MQTT协议与IEC 60870-5-104协议之间的双向转换和通信
 * 
 * @author zyb
 * @date 2025-10-30
 * @version 1.0
 */

#include "../include/iec104_protocol_bridge.h"
#include "../../../../common/logs/include/logger.h"
#include "../../../../common/json/include/json_utils.h"
#include "../../../../common/json/include/param_parser.h"

// 引入104协议栈核心组件
#include "../../core/common/types/include/protocol_types.h"
#include "../../core/common/types/include/constants.h"
#include "../../core/common/error/include/error_codes.h"
#include "../../core/protocol/asdu/include/asdu_assembler.h"
#include "../../core/protocol/asdu/include/asdu_parser.h"
#include "../../core/protocol/apdu/include/apdu_assembler.h"
#include "../../core/protocol/apdu/include/apdu_parser.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cJSON.h>

// 日志模块名称
#define LOG_MODULE_NAME "IEC104_PROTOCOL_BRIDGE"

// 104协议常量（从core使用）
#define IEC104_COMMON_ADDRESS 1         // 公共地址
#define IEC104_COT_ACTIVATION 6          // 传送原因：激活
#define IEC104_TYPE_SINGLE_COMMAND 45    // C_SC_NA_1
#define IEC104_TYPE_DOUBLE_COMMAND 46    // C_DC_NA_1
#define IEC104_TYPE_MEASURED_VALUE 13    // M_ME_NC_1

/* ==================== 辅助函数 ==================== */

/**
 * @brief 安全的字符串复制函数（避免strncpy截断警告）
 * @param dest 目标缓冲区
 * @param src 源字符串
 * @param dest_size 目标缓冲区大小
 */
static inline void safe_strncpy(char *dest, const char *src, size_t dest_size) {
    if (dest == NULL || src == NULL || dest_size == 0) {
        return;
    }
    size_t src_len = strlen(src);
    size_t copy_len = (src_len < dest_size - 1) ? src_len : (dest_size - 1);
    memcpy(dest, src, copy_len);
    dest[copy_len] = '\0';
}

/* ==================== 数据结构定义 ==================== */

/**
 * @brief IEC 104协议桥接私有数据
 */
typedef struct iec104_protocol_bridge {
    iec104_protocol_bridge_config_t config;    /* 配置信息 */
    iec104_protocol_bridge_stats_t stats;      /* 统计信息 */
    
    /* 104设备连接 */
    int device_socket;                  /* 设备套接字 */
    bool device_connected;              /* 设备连接状态 */
    bool startdt_activated;             /* STARTDT激活状态 */
    
    /* 104协议序列号管理 */
    uint16_t send_seq;                  /* 发送序列号 (0-32767) */
    uint16_t receive_seq;               /* 接收序列号 (0-32767) */
    
    /* 线程相关 */
    pthread_t monitor_thread;           /* 监控线程 */
    pthread_t report_thread;            /* 上报线程 */
    bool threads_running;               /* 线程运行标志 */
    pthread_mutex_t mutex;              /* 互斥锁 */
    
    /* 错误日志频率控制 */
    time_t last_mqtt_error_log_time;    /* 上次MQTT错误日志时间 */
    
    /* 重连控制 */
    time_t last_reconnect_attempt;      /* 上次重连尝试时间 */
    
} iec104_protocol_bridge_t;

/* ==================== 内部函数声明 ==================== */

/* 104协议连接 */
static int connect_to_device(iec104_protocol_bridge_t* bridge);
static void disconnect_from_device(iec104_protocol_bridge_t* bridge);
static int send_104_command(iec104_protocol_bridge_t* bridge, uint32_t point_number, bool value);
static int send_testfr_con(iec104_protocol_bridge_t* bridge);
static int send_startdt_act(iec104_protocol_bridge_t* bridge);

/* MQTT消息处理 */
static int parse_mqtt_control_message(const uint8_t* payload, size_t payload_len,
                                     uint32_t* point_number, bool* value);

/* 设备数据监控和上报 */
static void* monitor_thread_func(void* arg);
static void* report_thread_func(void* arg);
static int read_device_data(iec104_protocol_bridge_t* bridge, uint8_t* buffer, size_t buffer_size);
static int process_received_apdu(iec104_protocol_bridge_t* bridge, const uint8_t* data, size_t data_len);
static int report_data_to_mqtt(iec104_protocol_bridge_t* bridge, const char* data_json);

/* ASDU数据上报 */
static int report_teleindication_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu);
static int report_telemetry_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu);
static int report_raw_asdu_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu);

/* ==================== 函数实现 ==================== */

/**
 * @brief 创建IEC 104协议桥接
 */
iec104_protocol_bridge_handle_t iec104_protocol_bridge_create(const iec104_protocol_bridge_config_t* config) {
    if (config == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "配置参数为空");
        return NULL;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "创建IEC 104协议桥接模块");
    
    // 分配内存
    iec104_protocol_bridge_t* bridge = (iec104_protocol_bridge_t*)malloc(sizeof(iec104_protocol_bridge_t));
    if (bridge == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "内存分配失败");
        return NULL;
    }
    
    // 初始化结构
    memset(bridge, 0, sizeof(iec104_protocol_bridge_t));
    memcpy(&bridge->config, config, sizeof(iec104_protocol_bridge_config_t));
    bridge->device_socket = -1;
    bridge->device_connected = false;
    bridge->startdt_activated = false;
    bridge->last_mqtt_error_log_time = 0;
    bridge->last_reconnect_attempt = 0;
    
    // 初始化104协议序列号
    bridge->send_seq = 0;
    bridge->receive_seq = 0;
    
    // 初始化互斥锁
    if (pthread_mutex_init(&bridge->mutex, NULL) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "互斥锁初始化失败");
        free(bridge);
        return NULL;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "成功 IEC 104协议桥接模块创建成功");
    
    return (iec104_protocol_bridge_handle_t)bridge;
}

/**
 * @brief 销毁IEC 104协议桥接
 */
int iec104_protocol_bridge_destroy(iec104_protocol_bridge_handle_t bridge) {
    if (bridge == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_INFO(LOG_MODULE_NAME, "销毁协议桥接模块");
    
    // 确保已停止
    if (br->threads_running) {
        iec104_protocol_bridge_stop(bridge);
    }
    
    // 断开设备连接
    disconnect_from_device(br);
    
    // 销毁互斥锁
    pthread_mutex_destroy(&br->mutex);
    
    // 释放内存
    free(br);
    
    LOG_INFO(LOG_MODULE_NAME, "协议桥接模块已销毁");
    
    return 0;
}

/**
 * @brief 启动协议桥接
 */
int iec104_protocol_bridge_start(iec104_protocol_bridge_handle_t bridge) {
    if (bridge == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_INFO(LOG_MODULE_NAME, "启动协议桥接服务");
    
    pthread_mutex_lock(&br->mutex);
    
    if (br->threads_running) {
        LOG_WARN(LOG_MODULE_NAME, "协议桥接服务已在运行");
        pthread_mutex_unlock(&br->mutex);
        return 0;
    }
    
    // 尝试连接到104设备（失败时也会启动线程，由线程负责重连）
    int connect_result = connect_to_device(br);
    if (connect_result != 0) {
        LOG_WARN(LOG_MODULE_NAME, "104设备连接失败，将在监控线程中每5分钟重试连接");
    }
    
    // 启动监控线程（即使连接失败也启动，用于重连）
    br->threads_running = true;
    if (pthread_create(&br->monitor_thread, NULL, monitor_thread_func, br) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "创建监控线程失败");
        br->threads_running = false;
        disconnect_from_device(br);
        pthread_mutex_unlock(&br->mutex);
        return -1;
    }
    
    // 启动上报线程
    if (pthread_create(&br->report_thread, NULL, report_thread_func, br) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "创建上报线程失败");
        br->threads_running = false;
        pthread_cancel(br->monitor_thread);
        pthread_join(br->monitor_thread, NULL);
        disconnect_from_device(br);
        pthread_mutex_unlock(&br->mutex);
        return -1;
    }
    
    pthread_mutex_unlock(&br->mutex);
    
    LOG_INFO(LOG_MODULE_NAME, "成功 协议桥接服务启动成功");
    
    return 0;
}

/**
 * @brief 停止协议桥接
 */
int iec104_protocol_bridge_stop(iec104_protocol_bridge_handle_t bridge) {
    if (bridge == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_INFO(LOG_MODULE_NAME, "停止协议桥接服务");
    
    pthread_mutex_lock(&br->mutex);
    
    if (!br->threads_running) {
        pthread_mutex_unlock(&br->mutex);
        return 0;
    }
    
    br->threads_running = false;
    
    pthread_mutex_unlock(&br->mutex);
    
    // 等待线程退出
    pthread_join(br->monitor_thread, NULL);
    pthread_join(br->report_thread, NULL);
    
    // 断开设备连接
    disconnect_from_device(br);
    
    LOG_INFO(LOG_MODULE_NAME, "协议桥接服务已停止");
    
    return 0;
}

/**
 * @brief 处理MQTT消息
 */
int iec104_protocol_bridge_handle_mqtt_message(iec104_protocol_bridge_handle_t bridge,
                                        const char* topic,
                                        const uint8_t* payload,
                                        size_t payload_len) {
    if (bridge == NULL || topic == NULL || payload == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_INFO(LOG_MODULE_NAME, "处理MQTT控制消息");
    
    // 解析MQTT消息
    uint32_t point_number = 0;
    bool value = false;
    
    if (parse_mqtt_control_message(payload, payload_len, &point_number, &value) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "解析MQTT消息失败");
        pthread_mutex_lock(&br->mutex);
        br->stats.conversion_errors++;
        pthread_mutex_unlock(&br->mutex);
        return -1;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "MQTT控制命令: 点号=%u, 值=%d", point_number, value);
    
    // 发送104协议命令
    if (send_104_command(br, point_number, value) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "发送104命令失败");
        pthread_mutex_lock(&br->mutex);
        br->stats.send_errors++;
        pthread_mutex_unlock(&br->mutex);
        return -1;
    }
    
    // 更新统计
    pthread_mutex_lock(&br->mutex);
    br->stats.mqtt_to_iec104_count++;
    pthread_mutex_unlock(&br->mutex);
    
    LOG_INFO(LOG_MODULE_NAME, "成功 MQTT消息处理成功");
    
    return 0;
}

/**
 * @brief 上报104设备数据到MQTT
 */
int iec104_protocol_bridge_report_device_data(iec104_protocol_bridge_handle_t bridge,
                                       const char* data_type,
                                       const uint8_t* data,
                                       size_t data_len) {
    if (bridge == NULL || data_type == NULL || data == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_DEBUG(LOG_MODULE_NAME, "上报设备数据: 类型=%s, 长度=%zu", data_type, data_len);
    
    // 构造JSON格式的数据
    char json_buffer[4096];
    snprintf(json_buffer, sizeof(json_buffer),
             "{\"type\":\"%s\",\"timestamp\":%ld,\"data\":\"%.*s\"}",
             data_type, time(NULL), (int)data_len, data);
    
    // 上报到MQTT
    if (report_data_to_mqtt(br, json_buffer) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "上报数据到MQTT失败");
        pthread_mutex_lock(&br->mutex);
        br->stats.send_errors++;
        pthread_mutex_unlock(&br->mutex);
        return -1;
    }
    
    // 更新统计
    pthread_mutex_lock(&br->mutex);
    br->stats.iec104_to_mqtt_count++;
    pthread_mutex_unlock(&br->mutex);
    
    return 0;
}

/**
 * @brief 获取桥接统计信息
 */
int iec104_protocol_bridge_get_stats(iec104_protocol_bridge_handle_t bridge,
                              iec104_protocol_bridge_stats_t* stats) {
    if (bridge == NULL || stats == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    pthread_mutex_lock(&br->mutex);
    memcpy(stats, &br->stats, sizeof(iec104_protocol_bridge_stats_t));
    pthread_mutex_unlock(&br->mutex);
    
    return 0;
}

/**
 * @brief 重置桥接统计信息
 */
int iec104_protocol_bridge_reset_stats(iec104_protocol_bridge_handle_t bridge) {
    if (bridge == NULL) {
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    pthread_mutex_lock(&br->mutex);
    memset(&br->stats, 0, sizeof(iec104_protocol_bridge_stats_t));
    pthread_mutex_unlock(&br->mutex);
    
    LOG_INFO(LOG_MODULE_NAME, "统计信息已重置");
    
    return 0;
}

/**
 * @brief 发送104协议控制命令
 */
int iec104_protocol_bridge_send_command(iec104_protocol_bridge_handle_t bridge,
                                         uint32_t point_number,
                                         bool value) {
    if (bridge == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "桥接句柄为空");
        return -1;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    
    LOG_INFO(LOG_MODULE_NAME, "发送104控制命令: 点号=%u, 值=%s", 
             point_number, value ? "ON(合)" : "OFF(分)");
    
    return send_104_command(br, point_number, value);
}

/**
 * @brief 检查104设备连接状态
 */
bool iec104_protocol_bridge_is_connected(iec104_protocol_bridge_handle_t bridge) {
    if (bridge == NULL) {
        return false;
    }
    
    iec104_protocol_bridge_t* br = (iec104_protocol_bridge_t*)bridge;
    return br->device_connected && br->device_socket >= 0;
}

/* ==================== 内部函数实现 ==================== */

/**
 * @brief 连接到104设备
 */
static int connect_to_device(iec104_protocol_bridge_t* bridge) {
    LOG_INFO(LOG_MODULE_NAME, "正在尝试连接104设备: %s:%u", 
             bridge->config.device_ip, bridge->config.device_port);
    
    // 创建套接字
    bridge->device_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (bridge->device_socket < 0) {
        LOG_ERROR(LOG_MODULE_NAME, "创建套接字失败");
        return -1;
    }
    
    // 配置服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(bridge->config.device_port);
    
    if (inet_pton(AF_INET, bridge->config.device_ip, &server_addr.sin_addr) <= 0) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的IP地址");
        close(bridge->device_socket);
        bridge->device_socket = -1;
        return -1;
    }
    
    // 连接到服务器
    if (connect(bridge->device_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        LOG_WARN(LOG_MODULE_NAME, "连接104设备失败: %s", strerror(errno));
        LOG_WARN(LOG_MODULE_NAME, "104连接状态: DISCONNECTED");
        close(bridge->device_socket);
        bridge->device_socket = -1;
        return -1;
    }
    
    bridge->device_connected = true;
    
    LOG_INFO(LOG_MODULE_NAME, "成功 104设备连接成功");
    LOG_INFO(LOG_MODULE_NAME, "104连接状态: CONNECTED");
    
    // 连接成功后发送STARTDT激活数据传输
    bridge->startdt_activated = false;  // 重置激活状态
    LOG_DEBUG(LOG_MODULE_NAME, "重置STARTDT激活状态: startdt_activated=false");
    if (send_startdt_act(bridge) == 0) {
        LOG_INFO(LOG_MODULE_NAME, "STARTDT激活已发送，等待确认");
        LOG_DEBUG(LOG_MODULE_NAME, "等待STARTDT确认，当前状态: startdt_activated=false");
    } else {
        LOG_ERROR(LOG_MODULE_NAME, "发送STARTDT激活失败");
    }
    
    return 0;
}

/**
 * @brief 断开104设备连接
 */
static void disconnect_from_device(iec104_protocol_bridge_t* bridge) {
    if (bridge->device_socket >= 0) {
        LOG_INFO(LOG_MODULE_NAME, "断开104设备连接");
        close(bridge->device_socket);
        bridge->device_socket = -1;
    }
    bridge->device_connected = false;
    bridge->startdt_activated = false;  // 断开连接时重置激活状态
    LOG_DEBUG(LOG_MODULE_NAME, "断开连接，重置STARTDT激活状态: startdt_activated=false");
    LOG_WARN(LOG_MODULE_NAME, "104连接状态: DISCONNECTED");
}

/**
 * @brief 发送104协议命令（使用完整协议栈）
 */
static int send_104_command(iec104_protocol_bridge_t* bridge, uint32_t point_number, bool value) {
    LOG_DEBUG(LOG_MODULE_NAME, "准备发送104命令: 点号=%u, 值=%d", point_number, value);
    LOG_DEBUG(LOG_MODULE_NAME, "检查连接状态: device_connected=%d, device_socket=%d", 
             bridge->device_connected, bridge->device_socket);
    
    if (!bridge->device_connected || bridge->device_socket < 0) {
        LOG_ERROR(LOG_MODULE_NAME, "设备未连接: device_connected=%d, device_socket=%d", 
                  bridge->device_connected, bridge->device_socket);
        return -1;
    }
    
    // 检查socket是否有效（使用getsockopt检查）
    int socket_error = 0;
    socklen_t len = sizeof(socket_error);
    if (getsockopt(bridge->device_socket, SOL_SOCKET, SO_ERROR, &socket_error, &len) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "检查socket状态失败: %s", strerror(errno));
        bridge->device_connected = false;
        return -1;
    }
    if (socket_error != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "Socket有错误: %s", strerror(socket_error));
        bridge->device_connected = false;
        return -1;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "Socket状态检查通过");
    
    // 检查STARTDT是否已激活
    LOG_DEBUG(LOG_MODULE_NAME, "检查STARTDT激活状态: startdt_activated=%d", bridge->startdt_activated);
    if (!bridge->startdt_activated) {
        LOG_ERROR(LOG_MODULE_NAME, "STARTDT未激活，无法发送命令。请等待STARTDT确认");
        LOG_DEBUG(LOG_MODULE_NAME, "当前状态: device_connected=%d, startdt_activated=%d", 
                 bridge->device_connected, bridge->startdt_activated);
        return -1;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "STARTDT激活状态检查通过");
    
    LOG_INFO(LOG_MODULE_NAME, "发送104命令: 点号=%u, 值=%d", point_number, value);
    
    // 1. 构造单点命令信息对象
    single_command_info_t cmd_info;
    cmd_info.info_addr = (u16)point_number;
    
    // 构造单点命令状态字节 (SCO)
    // Bit 0: scs (单点命令状态, 0=off, 1=on)
    // Bit 1: reserved
    // Bit 2-6: qu (限定词, 0=无附加定义)
    // Bit 7: se (选择/执行, 0=执行)
    cmd_info.sco = (value ? 0x01 : 0x00);  // scs位
    cmd_info.qos = 0x00;  // 限定词：无附加定义，直接执行
    
    // 2. 组装ASDU (C_SC_NA_1)
    LOG_DEBUG(LOG_MODULE_NAME, "开始组装ASDU (C_SC_NA_1): 信息对象地址=%u, 值=%s",
             (unsigned)point_number, value ? "ON(合)" : "OFF(分)");
    uint8_t asdu_buffer[256];
    size_t asdu_size = 0;
    protocol_error_t result = assemble_single_command_asdu(
        (cause_of_transmission_t)IEC104_COT_ACTIVATION,  // 传送原因：激活
        (asdu_common_address_t)IEC104_COMMON_ADDRESS,    // 公共地址
        &cmd_info,                                        // 命令信息对象
        1,                                                // 信息对象数量
        asdu_buffer,                                      // 输出缓冲区
        sizeof(asdu_buffer),                              // 缓冲区大小
        &asdu_size                                        // 实际大小
    );
    
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "组装ASDU失败: 错误码=%d", result);
        return -1;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "ASDU组装完成，长度=%zu字节", asdu_size);
    
    // 3. 构造ASDU结构用于APDU组装
    asdu_t asdu;
    memset(&asdu, 0, sizeof(asdu));
    asdu.type_id = IEC104_TYPE_SINGLE_COMMAND;
    asdu.vsq.number_of_objects = 1;
    asdu.vsq.sq = 0;
    asdu.cause_of_transmission = IEC104_COT_ACTIVATION;
    asdu.common_address = IEC104_COMMON_ADDRESS;
    asdu.information_objects = asdu_buffer + 6;  // 跳过ASDU头部
    asdu.information_objects_length = asdu_size - 6;
    asdu.length = asdu_size;
    
    // 4. 组装I格式APDU
    uint8_t apdu_buffer[256];
    size_t apdu_size = 0;
    
    // 更新发送序列号
    pthread_mutex_lock(&bridge->mutex);
    uint16_t current_send_seq = bridge->send_seq;
    uint16_t current_recv_seq = bridge->receive_seq;
    bridge->send_seq = (bridge->send_seq + 1) & 0x7FFF;  // 限制在0-32767
    pthread_mutex_unlock(&bridge->mutex);
    
    LOG_DEBUG(LOG_MODULE_NAME, "序列号信息: 当前发送序号=%u, 当前接收序号=%u, 下一发送序号=%u", 
             current_send_seq, current_recv_seq, bridge->send_seq);
    LOG_DEBUG(LOG_MODULE_NAME, "开始组装I格式APDU...");
    result = assemble_i_format_apdu_with_asdu(
        &asdu,                                           // ASDU
        current_send_seq,                                // 发送序列号
        current_recv_seq,                                // 接收序列号
        apdu_buffer,                                     // 输出缓冲区
        sizeof(apdu_buffer),                             // 缓冲区大小
        &apdu_size                                       // 实际大小
    );
    
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "组装APDU失败: 错误码=%d", result);
        return -1;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "APDU组装完成，长度=%zu字节 (发送序号=%u, 接收序号=%u)", 
              apdu_size, current_send_seq, current_recv_seq);
    
    // 5. 发送APDU前再次检查连接状态
    LOG_DEBUG(LOG_MODULE_NAME, "发送APDU前检查连接状态: device_connected=%d, device_socket=%d", 
             bridge->device_connected, bridge->device_socket);
    
    if (!bridge->device_connected || bridge->device_socket < 0) {
        LOG_ERROR(LOG_MODULE_NAME, "发送前连接已断开: device_connected=%d, device_socket=%d", 
                  bridge->device_connected, bridge->device_socket);
        return -1;
    }
    
    // 打印APDU内容（前16字节）用于调试
    LOG_DEBUG(LOG_MODULE_NAME, "准备发送APDU，长度=%zu字节", apdu_size);
    if (apdu_size > 0) {
        char hex_str[64] = {0};
        int hex_len = 0;
        int print_len = (apdu_size < 16) ? apdu_size : 16;
        for (int i = 0; i < print_len && hex_len < 63; i++) {
            hex_len += snprintf(hex_str + hex_len, 64 - hex_len, "%02X ", apdu_buffer[i]);
        }
        LOG_DEBUG(LOG_MODULE_NAME, "APDU内容（前%d字节）: %s", print_len, hex_str);
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "调用send()发送APDU到104设备，socket=%d, 长度=%zu", 
             bridge->device_socket, apdu_size);
    ssize_t sent = send(bridge->device_socket, apdu_buffer, apdu_size, 0);
    
    if (sent < 0) {
        int err = errno;
        LOG_ERROR(LOG_MODULE_NAME, "发送104命令失败: %s (errno=%d)", strerror(err), err);
        LOG_DEBUG(LOG_MODULE_NAME, "发送失败详情: socket=%d, device_connected=%d, apdu_size=%zu", 
                 bridge->device_socket, bridge->device_connected, apdu_size);
        
        // 如果是Broken pipe或Connection reset，说明连接已断开
        if (err == EPIPE || err == ECONNRESET) {
            LOG_ERROR(LOG_MODULE_NAME, "检测到连接已断开，更新连接状态");
            bridge->device_connected = false;
            if (bridge->device_socket >= 0) {
                close(bridge->device_socket);
                bridge->device_socket = -1;
            }
        }
        return -1;
    }
    
    if (sent != (ssize_t)apdu_size) {
        LOG_WARN(LOG_MODULE_NAME, "部分发送: 期望发送%zu字节，实际发送%zd字节", apdu_size, sent);
    }
    
    LOG_INFO(LOG_MODULE_NAME, "成功 104命令发送成功: %zd字节 (发送序号=%u, 接收序号=%u)", 
             sent, current_send_seq, current_recv_seq);
    LOG_DEBUG(LOG_MODULE_NAME, "发送完成，当前连接状态: device_connected=%d, device_socket=%d, startdt_activated=%d", 
             bridge->device_connected, bridge->device_socket, bridge->startdt_activated);
    LOG_DEBUG(LOG_MODULE_NAME, "发送完成，序列号状态: 当前发送序号=%u, 当前接收序号=%u, 下一发送序号=%u", 
             current_send_seq, current_recv_seq, bridge->send_seq);
    
    // 更新统计
    pthread_mutex_lock(&bridge->mutex);
    bridge->stats.mqtt_to_iec104_count++;
    pthread_mutex_unlock(&bridge->mutex);
    
    return 0;
}

/**
 * @brief 解析MQTT控制消息
 */
static int parse_mqtt_control_message(const uint8_t* payload, size_t payload_len,
                                     uint32_t* point_number, bool* value) {
    // 假设MQTT消息是JSON格式: {"point": 1, "value": true}
    // 实际应用中需要使用cJSON库解析
    
    // 简化版本：直接从JSON字符串中提取
    char* json_str = (char*)malloc(payload_len + 1);
    if (json_str == NULL) {
        return -1;
    }
    
    memcpy(json_str, payload, payload_len);
    json_str[payload_len] = '\0';
    
    // 查找point和value字段
    char* point_str = strstr(json_str, "\"point\"");
    char* value_str = strstr(json_str, "\"value\"");
    
    if (point_str && value_str) {
        // 提取点号
        sscanf(point_str, "\"point\": %u", point_number);
        
        // 提取值
        if (strstr(value_str, "true")) {
            *value = true;
        } else if (strstr(value_str, "false")) {
            *value = false;
        } else {
            int int_value;
            sscanf(value_str, "\"value\": %d", &int_value);
            *value = (int_value != 0);
        }
        
        free(json_str);
        return 0;
    }
    
    free(json_str);
    return -1;
}

/**
 * @brief 监控线程 - 监控设备数据（使用完整协议栈）
 * @details 同时负责104设备的重连机制，每5分钟检查一次连接状态并尝试重连
 */
static void* monitor_thread_func(void* arg) {
    iec104_protocol_bridge_t* bridge = (iec104_protocol_bridge_t*)arg;
    
    LOG_INFO(LOG_MODULE_NAME, "监控线程启动");
    
    uint8_t buffer[1024];
    time_t current_time;
    const time_t reconnect_interval = 300;  // 5分钟 = 300秒
    
    // 初始化上次重连时间
    pthread_mutex_lock(&bridge->mutex);
    if (bridge->last_reconnect_attempt == 0) {
        bridge->last_reconnect_attempt = time(NULL);
    }
    pthread_mutex_unlock(&bridge->mutex);
    
    while (bridge->threads_running) {
        current_time = time(NULL);
        
        // 检查连接状态，如果未连接则尝试重连（每5分钟一次）
        pthread_mutex_lock(&bridge->mutex);
        bool need_reconnect = !bridge->device_connected && 
                              (current_time - bridge->last_reconnect_attempt >= reconnect_interval);
        pthread_mutex_unlock(&bridge->mutex);
        
        if (need_reconnect) {
            LOG_INFO(LOG_MODULE_NAME, "检测到104设备未连接，尝试重连（心跳重试，每5分钟）...");
            pthread_mutex_lock(&bridge->mutex);
            bridge->last_reconnect_attempt = current_time;
            pthread_mutex_unlock(&bridge->mutex);
            
            if (connect_to_device(bridge) == 0) {
                LOG_INFO(LOG_MODULE_NAME, "104设备重连成功");
            } else {
                LOG_WARN(LOG_MODULE_NAME, "104设备重连失败，将在5分钟后再次尝试");
            }
        }
        
        // 如果已连接，读取设备数据
        pthread_mutex_lock(&bridge->mutex);
        bool is_connected = bridge->device_connected;
        pthread_mutex_unlock(&bridge->mutex);
        
        if (is_connected) {
            int len = read_device_data(bridge, buffer, sizeof(buffer));
            if (len > 0) {
                LOG_DEBUG(LOG_MODULE_NAME, "收到设备数据: %d字节", len);
                
                // 解析104协议APDU数据
                if (process_received_apdu(bridge, buffer, len) == 0) {
                    LOG_DEBUG(LOG_MODULE_NAME, "APDU解析并处理成功");
                }
            } else if (len < 0) {
                // 读取失败，可能连接断开
                pthread_mutex_lock(&bridge->mutex);
                if (bridge->device_connected) {
                    LOG_WARN(LOG_MODULE_NAME, "读取设备数据失败，连接可能已断开");
                    bridge->device_connected = false;
                    if (bridge->device_socket >= 0) {
                        close(bridge->device_socket);
                        bridge->device_socket = -1;
                    }
                }
                pthread_mutex_unlock(&bridge->mutex);
            }
        }
        
        // 短暂休眠
        struct timespec sleep_time = {0, 100000000};  // 100ms (0秒 + 100,000,000纳秒)
        nanosleep(&sleep_time, NULL);
    }
    
    LOG_INFO(LOG_MODULE_NAME, "监控线程退出");
    
    return NULL;
}

/**
 * @brief 上报线程 - 定期上报设备状态
 */
static void* report_thread_func(void* arg) {
    iec104_protocol_bridge_t* bridge = (iec104_protocol_bridge_t*)arg;
    
    LOG_INFO(LOG_MODULE_NAME, "上报线程启动");
    
    uint32_t interval = bridge->config.data_report_interval;
    
    while (bridge->threads_running) {
        // 定期上报设备状态
        char status_json[512];
        snprintf(status_json, sizeof(status_json),
                 "{\"device_connected\":%s,\"timestamp\":%ld}",
                 bridge->device_connected ? "true" : "false", time(NULL));
        
        report_data_to_mqtt(bridge, status_json);
        
        // 等待下一个上报周期
        for (uint32_t i = 0; i < interval && bridge->threads_running; i++) {
            sleep(1);
        }
    }
    
    LOG_INFO(LOG_MODULE_NAME, "上报线程退出");
    
    return NULL;
}

/**
 * @brief 读取设备数据
 */
static int read_device_data(iec104_protocol_bridge_t* bridge, uint8_t* buffer, size_t buffer_size) {
    if (!bridge->device_connected || bridge->device_socket < 0) {
        return -1;
    }
    
    // 设置非阻塞接收
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 100000; // 100ms (注意：这里原来写错了tv.tv_sec，应该是tv.tv_usec)
    setsockopt(bridge->device_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    
    ssize_t received = recv(bridge->device_socket, buffer, buffer_size, 0);
    if (received < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            return 0; // 超时或无数据
        }
        LOG_ERROR(LOG_MODULE_NAME, "接收数据失败: %s", strerror(errno));
        return -1;
    }
    
    return (int)received;
}

/**
 * @brief 处理接收到的APDU数据（使用完整协议栈）
 */
static int process_received_apdu(iec104_protocol_bridge_t* bridge, const uint8_t* data, size_t data_len) {
    if (data == NULL || data_len < APDU_MIN_LENGTH) {
        LOG_WARN(LOG_MODULE_NAME, "收到的数据太短，无法解析: %zu字节", data_len);
        return -1;
    }
    
    // 解析APDU
    apdu_t apdu;
    protocol_error_t result = parse_apdu(data, data_len, &apdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU解析失败: 错误码=%d", result);
        return -1;
    }
    
    // 检查APDU格式
    apdu_format_t format = detect_apdu_format(&apdu);
    
    switch (format) {
        case APDU_FORMAT_I: {
            // I格式：包含数据的帧
            LOG_DEBUG(LOG_MODULE_NAME, "收到I格式APDU");
            
            // 更新接收序列号
            uint16_t recv_seq = (apdu.control_field.control1 | (apdu.control_field.control2 << 8)) >> 1;
            pthread_mutex_lock(&bridge->mutex);
            bridge->receive_seq = (recv_seq + 1) & 0x7FFF;
            pthread_mutex_unlock(&bridge->mutex);
            
            LOG_DEBUG(LOG_MODULE_NAME, "更新接收序列号: %u", bridge->receive_seq);
            
            // 解析ASDU并上报数据到MQTT
            // ASDU数据长度 = APDU长度 - 控制域长度(4字节)
            size_t asdu_data_len = (apdu.length > 4) ? (apdu.length - 4) : 0;
            if (asdu_data_len > 0 && apdu.asdu_data != NULL) {
                asdu_t asdu;
                memset(&asdu, 0, sizeof(asdu));
                
                // 解析ASDU
                protocol_error_t asdu_result = parse_asdu(apdu.asdu_data, asdu_data_len, &asdu);
                if (asdu_result == PROTOCOL_SUCCESS) {
                    // 业务层面的语义解释（使用INFO级别）
                    LOG_INFO(LOG_MODULE_NAME, "========== 设备返回数据语义解释 ==========");
                    const char* type_name = "";
                    const char* cot_meaning = "";
                    const char* business_meaning = "";
                    
                    // 根据类型ID确定数据类型
                    switch (asdu.type_id) {
                        case 1:   type_name = "单点信息(遥信)"; break;
                        case 3:   type_name = "双点信息"; break;
                        case 9:   type_name = "测量值(遥测)"; break;
                        case 11:  type_name = "测量值(标度化值)"; break;
                        case 13:  type_name = "测量值(短浮点数)"; break;
                        case 30:  type_name = "带时标的单点信息"; break;
                        case 34:  type_name = "带时标的测量值"; break;
                        case 35:  type_name = "带时标的测量值(标度化值)"; break;
                        case 36:  type_name = "带时标的测量值(短浮点数)"; break;
                        case 45:  type_name = "单点命令"; break;
                        case 46:  type_name = "双点命令"; break;
                        case 100: type_name = "总召唤命令"; break;
                        default:  type_name = "未知类型"; break;
                    }
                    
                    // 根据传送原因确定业务含义
                    switch (asdu.cause_of_transmission) {
                        case 0:   cot_meaning = "未使用"; break;
                        case 1:   cot_meaning = "周期/循环"; break;
                        case 2:   cot_meaning = "背景扫描"; break;
                        case 3:   cot_meaning = "自发"; break;
                        case 4:   cot_meaning = "初始化"; break;
                        case 5:   cot_meaning = "请求或被请求"; break;
                        case 6:   cot_meaning = "激活"; break;
                        case 7:   cot_meaning = "激活确认"; break;
                        case 8:   cot_meaning = "停止激活"; break;
                        case 9:   cot_meaning = "停止激活确认"; break;
                        case 10:  cot_meaning = "激活终止"; break;
                        case 11:  cot_meaning = "返回信息"; break;
                        case 12:  cot_meaning = "返回信息(否定)"; break;
                        case 13:  cot_meaning = "文件传输"; break;
                        case 14:  cot_meaning = "认证"; break;
                        case 15:  cot_meaning = "会话密钥"; break;
                        case 16:  cot_meaning = "用户数据"; break;
                        case 17:  cot_meaning = "制造商特定"; break;
                        default:  cot_meaning = "未知原因"; break;
                    }
                    
                    // 组合业务含义
                    if (asdu.type_id == 45 || asdu.type_id == 46) {
                        // 命令类型
                        if (asdu.cause_of_transmission == 6) {
                            business_meaning = "这是对单点命令的激活请求";
                        } else if (asdu.cause_of_transmission == 7) {
                            business_meaning = "✓ 这是对单点命令的激活确认，表示命令已被设备接受并执行";
                        } else if (asdu.cause_of_transmission == 8) {
                            business_meaning = "这是对单点命令的停止激活请求";
                        } else if (asdu.cause_of_transmission == 9) {
                            business_meaning = "这是对单点命令的停止激活确认";
                        } else if (asdu.cause_of_transmission == 10) {
                            business_meaning = "这是对单点命令的激活终止";
                        } else if (asdu.cause_of_transmission == 11) {
                            business_meaning = "这是对单点命令的返回信息";
                        } else if (asdu.cause_of_transmission == 12) {
                            business_meaning = "✗ 这是对单点命令的返回信息(否定)，表示命令被拒绝";
                        } else {
                            business_meaning = "这是单点命令数据";
                        }
                    } else if (asdu.type_id == 100) {
                        // 总召唤命令
                        if (asdu.cause_of_transmission == 6) {
                            business_meaning = "这是总召唤命令的激活请求";
                        } else if (asdu.cause_of_transmission == 7) {
                            business_meaning = "✓ 这是总召唤命令的激活确认，设备将开始上传数据";
                        } else if (asdu.cause_of_transmission == 8) {
                            business_meaning = "这是总召唤命令的停止激活请求";
                        } else if (asdu.cause_of_transmission == 9) {
                            business_meaning = "这是总召唤命令的停止激活确认";
                        } else {
                            business_meaning = "这是总召唤命令数据";
                        }
                    } else if (asdu.type_id == 1 || asdu.type_id == 3 || asdu.type_id == 30) {
                        // 遥信数据
                        if (asdu.cause_of_transmission == 1) {
                            business_meaning = "这是设备周期上报的遥信数据";
                        } else if (asdu.cause_of_transmission == 2) {
                            business_meaning = "这是设备背景扫描上报的遥信数据";
                        } else if (asdu.cause_of_transmission == 3) {
                            business_meaning = "这是设备自发上报的遥信数据(状态变化)";
                        } else if (asdu.cause_of_transmission == 4) {
                            business_meaning = "这是设备初始化上报的遥信数据";
                        } else if (asdu.cause_of_transmission == 5) {
                            business_meaning = "这是设备响应请求上报的遥信数据";
                        } else {
                            business_meaning = "这是设备上报的遥信数据";
                        }
                    } else if (asdu.type_id == 9 || asdu.type_id == 11 || asdu.type_id == 13 || 
                              asdu.type_id == 34 || asdu.type_id == 35 || asdu.type_id == 36) {
                        // 遥测数据
                        if (asdu.cause_of_transmission == 1) {
                            business_meaning = "这是设备周期上报的遥测数据";
                        } else if (asdu.cause_of_transmission == 2) {
                            business_meaning = "这是设备背景扫描上报的遥测数据";
                        } else if (asdu.cause_of_transmission == 3) {
                            business_meaning = "这是设备自发上报的遥测数据(数值变化)";
                        } else if (asdu.cause_of_transmission == 4) {
                            business_meaning = "这是设备初始化上报的遥测数据";
                        } else if (asdu.cause_of_transmission == 5) {
                            business_meaning = "这是设备响应请求上报的遥测数据";
                        } else {
                            business_meaning = "这是设备上报的遥测数据";
                        }
                    } else {
                        business_meaning = "这是设备返回的数据";
                    }
                    
                    LOG_INFO(LOG_MODULE_NAME, "数据类型: %s (类型ID=%u)", type_name, asdu.type_id);
                    LOG_INFO(LOG_MODULE_NAME, "传送原因: %s (原因码=%u)", cot_meaning, asdu.cause_of_transmission);
                    LOG_INFO(LOG_MODULE_NAME, "业务含义: %s", business_meaning);
                    LOG_INFO(LOG_MODULE_NAME, "信息对象数量: %u个", asdu.vsq.number_of_objects);
                    LOG_INFO(LOG_MODULE_NAME, "公共地址: %u", asdu.common_address);
                    LOG_INFO(LOG_MODULE_NAME, "===========================================");
                    
                    // 详细解析信息对象数据
                    if (asdu.info_object_data != NULL && asdu.vsq.number_of_objects > 0) {
                        LOG_DEBUG(LOG_MODULE_NAME, "========== 信息对象数据详细解析 ==========");
                        LOG_DEBUG(LOG_MODULE_NAME, "信息对象数据长度: %zu字节", 
                                 asdu.length - ASDU_HEADER_SIZE);
                        LOG_DEBUG(LOG_MODULE_NAME, "信息对象数量: %u", asdu.vsq.number_of_objects);
                        LOG_DEBUG(LOG_MODULE_NAME, "结构类型: %s", 
                                 asdu.vsq.sq ? "连续结构(地址连续)" : "非连续结构(地址不连续)");
                        
                        // 打印信息对象原始数据（前32字节）
                        size_t info_data_len = asdu.length - ASDU_HEADER_SIZE;
                        int print_len = (info_data_len < 32) ? info_data_len : 32;
                        char hex_str[256] = {0};
                        int hex_len = 0;
                        for (int i = 0; i < print_len && hex_len < 255; i++) {
                            hex_len += snprintf(hex_str + hex_len, 256 - hex_len, "%02X ", 
                                               asdu.info_object_data[i]);
                        }
                        LOG_DEBUG(LOG_MODULE_NAME, "信息对象原始数据（前%d字节）: %s", print_len, hex_str);
                        
                        // 根据ASDU类型解析信息对象
                        size_t offset = 0;
                        if (asdu.vsq.sq == 0) {
                            // 非连续结构：每个信息对象都有地址
                            LOG_DEBUG(LOG_MODULE_NAME, "========== 非连续结构信息对象解析 ==========");
                            for (uint8_t i = 0; i < asdu.vsq.number_of_objects && i < 10; i++) {
                                LOG_DEBUG(LOG_MODULE_NAME, "--- 信息对象[%u] ---", i);
                                
                                // 解析信息对象地址（3字节，小端序）
                                if (offset + 3 <= info_data_len) {
                                    uint32_t info_addr = asdu.info_object_data[offset] | 
                                                        (asdu.info_object_data[offset+1] << 8) |
                                                        (asdu.info_object_data[offset+2] << 16);
                                    LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu-%zu]: 信息对象地址 = 0x%02X 0x%02X 0x%02X (%u)", 
                                             offset, offset+2,
                                             asdu.info_object_data[offset],
                                             asdu.info_object_data[offset+1],
                                             asdu.info_object_data[offset+2],
                                             info_addr);
                                    LOG_DEBUG(LOG_MODULE_NAME, "  含义: 信息对象地址，3字节，小端序");
                                    LOG_DEBUG(LOG_MODULE_NAME, "  说明: 标识具体的信息对象点号");
                                    offset += 3;
                                }
                                
                                // 根据类型ID解析数据
                                if (asdu.type_id == 1 || asdu.type_id == 30) {
                                    // M_SP_NA_1: 单点信息
                                    if (offset + 1 <= info_data_len) {
                                        uint8_t data_byte = asdu.info_object_data[offset];
                                        uint8_t siq = data_byte & 0x01;  // bit0: SIQ
                                        uint8_t iv = (data_byte >> 1) & 0x01;  // bit1: IV
                                        uint8_t nt = (data_byte >> 2) & 0x01;  // bit2: NT
                                        uint8_t sb = (data_byte >> 3) & 0x01;  // bit3: SB
                                        uint8_t bl = (data_byte >> 4) & 0x01;  // bit4: BL
                                        uint8_t ov = (data_byte >> 5) & 0x01;  // bit5: OV
                                        uint8_t res1 = (data_byte >> 6) & 0x01;  // bit6: RES1 (保留位)
                                        uint8_t res2 = (data_byte >> 7) & 0x01;  // bit7: RES2 (保留位)
                                        (void)res1;  // 未使用，消除警告
                                        (void)res2;  // 未使用，消除警告
                                        
                                        LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu]: 单点信息 = 0x%02X", offset, data_byte);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  含义: 单点信息对象数据");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit0 (SIQ): %d - %s", siq, siq ? "ON(合)" : "OFF(分)");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit1 (IV): %d - %s", iv, iv ? "无效" : "有效");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit2 (NT): %d - %s", nt, nt ? "非当前值" : "当前值");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit3 (SB): %d - %s", sb, sb ? "被取代" : "未被取代");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit4 (BL): %d - %s", bl, bl ? "被闭锁" : "未被闭锁");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit5 (OV): %d - %s", ov, ov ? "溢出" : "未溢出");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit6-7 (RES): 保留位");
                                        offset += 1;
                                    }
                                } else if (asdu.type_id == 13) {
                                    // M_ME_NC_1: 测量值，短浮点数
                                    if (offset + 4 <= info_data_len) {
                                        float value;
                                        memcpy(&value, &asdu.info_object_data[offset], 4);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu-%zu]: 测量值 = 0x%02X 0x%02X 0x%02X 0x%02X (%.2f)", 
                                                 offset, offset+3,
                                                 asdu.info_object_data[offset],
                                                 asdu.info_object_data[offset+1],
                                                 asdu.info_object_data[offset+2],
                                                 asdu.info_object_data[offset+3],
                                                 value);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  含义: 测量值，IEEE 754单精度浮点数，4字节");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  说明: 表示遥测数据的实际值");
                                        offset += 4;
                                    }
                                } else if (asdu.type_id == 45) {
                                    // C_SC_NA_1: 单点命令
                                    if (offset + 1 <= info_data_len) {
                                        uint8_t data_byte = asdu.info_object_data[offset];
                                        uint8_t scs = data_byte & 0x01;  // bit0: SCS
                                        uint8_t qu = (data_byte >> 2) & 0x1F;  // bit2-6: QU
                                        uint8_t se = (data_byte >> 7) & 0x01;  // bit7: SE
                                        
                                        LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu]: 单点命令 = 0x%02X", offset, data_byte);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  含义: 单点命令对象数据");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit0 (SCS): %d - %s", scs, scs ? "ON(合)" : "OFF(分)");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit1: 保留");
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit2-6 (QU): %d - 限定词", qu);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  bit7 (SE): %d - %s", se, se ? "选择执行" : "直接执行");
                                        offset += 1;
                                    }
                                } else {
                                    // 其他类型，只打印原始数据
                                    int data_len = (info_data_len - offset < 8) ? (info_data_len - offset) : 8;
                                    if (data_len > 0) {
                                        char data_hex[64] = {0};
                                        int data_hex_len = 0;
                                        for (int j = 0; j < data_len && data_hex_len < 63; j++) {
                                            data_hex_len += snprintf(data_hex + data_hex_len, 64 - data_hex_len, 
                                                                    "%02X ", asdu.info_object_data[offset + j]);
                                        }
                                        LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu-%zu]: 数据 = %s", 
                                                 offset, offset+data_len-1, data_hex);
                                        LOG_DEBUG(LOG_MODULE_NAME, "  含义: 信息对象数据（类型ID=%u）", asdu.type_id);
                                        offset += data_len;
                                    }
                                }
                            }
                            if (asdu.vsq.number_of_objects > 10) {
                                LOG_DEBUG(LOG_MODULE_NAME, "... (还有%u个信息对象未显示)", 
                                         asdu.vsq.number_of_objects - 10);
                            }
                        } else {
                            // 连续结构：只有第一个信息对象有地址
                            LOG_DEBUG(LOG_MODULE_NAME, "========== 连续结构信息对象解析 ==========");
                            uint32_t first_addr = 0;
                            if (offset + 3 <= info_data_len) {
                                first_addr = asdu.info_object_data[offset] | 
                                            (asdu.info_object_data[offset+1] << 8) |
                                            (asdu.info_object_data[offset+2] << 16);
                                LOG_DEBUG(LOG_MODULE_NAME, "字节[%zu-%zu]: 起始信息对象地址 = 0x%02X 0x%02X 0x%02X (%u)", 
                                         offset, offset+2,
                                         asdu.info_object_data[offset],
                                         asdu.info_object_data[offset+1],
                                         asdu.info_object_data[offset+2],
                                         first_addr);
                                LOG_DEBUG(LOG_MODULE_NAME, "含义: 第一个信息对象地址，3字节，小端序");
                                LOG_DEBUG(LOG_MODULE_NAME, "说明: 后续信息对象地址连续递增");
                                offset += 3;
                            }
                            
                            // 解析数据部分
                            int data_per_obj = (info_data_len - offset) / asdu.vsq.number_of_objects;
                            LOG_DEBUG(LOG_MODULE_NAME, "每个信息对象数据长度: %d字节", data_per_obj);
                            for (uint8_t i = 0; i < asdu.vsq.number_of_objects && i < 10 && 
                                 offset + data_per_obj <= info_data_len; i++) {
                                LOG_DEBUG(LOG_MODULE_NAME, "--- 信息对象[%u] (地址=%u) ---", i, 
                                         (first_addr + i));
                                char data_hex[64] = {0};
                                int data_hex_len = 0;
                                for (int j = 0; j < data_per_obj && data_hex_len < 63; j++) {
                                    data_hex_len += snprintf(data_hex + data_hex_len, 64 - data_hex_len, 
                                                            "%02X ", asdu.info_object_data[offset + j]);
                                }
                                LOG_DEBUG(LOG_MODULE_NAME, "  字节[%zu-%zu]: 数据 = %s", 
                                         offset, offset+data_per_obj-1, data_hex);
                                LOG_DEBUG(LOG_MODULE_NAME, "  含义: 信息对象数据（类型ID=%u）", asdu.type_id);
                                offset += data_per_obj;
                            }
                            if (asdu.vsq.number_of_objects > 10) {
                                LOG_DEBUG(LOG_MODULE_NAME, "... (还有%u个信息对象未显示)", 
                                         asdu.vsq.number_of_objects - 10);
                            }
                        }
                        LOG_DEBUG(LOG_MODULE_NAME, "===========================================");
                    }
                    
                    // 根据类型ID处理不同数据
                    switch (asdu.type_id) {
                        case 1:   // M_SP_NA_1: 单点信息（遥信）
                        case 3:   // M_DP_NA_1: 双点信息
                        case 30:  // M_SP_TB_1: 带时标的单点信息
                            report_teleindication_to_mqtt(bridge, &asdu);
                            break;
                            
                        case 9:   // M_ME_NA_1: 测量值（遥测）
                        case 11:  // M_ME_NB_1: 测量值，标度化值
                        case 13:  // M_ME_NC_1: 测量值，短浮点数
                        case 34:  // M_ME_TD_1: 带时标的测量值
                        case 35:  // M_ME_TE_1: 带时标的测量值，标度化值
                        case 36:  // M_ME_TF_1: 带时标的测量值，短浮点数
                            report_telemetry_to_mqtt(bridge, &asdu);
                            break;
                            
                        case 45:  // C_SC_NA_1: 单点命令
                        case 46:  // C_DC_NA_1: 双点命令
                            LOG_INFO(LOG_MODULE_NAME, "收到命令确认: 类型=%u (C_SC_NA_1/C_DC_NA_1), 对象数=%u", 
                                    asdu.type_id, asdu.vsq.number_of_objects);
                            LOG_DEBUG(LOG_MODULE_NAME, "命令确认详情: 公共地址=%u, 传送原因=%u", 
                                     asdu.common_address, asdu.cause_of_transmission);
                            break;
                            
                        case 100: // C_IC_NA_1: 总召唤命令
                            LOG_INFO(LOG_MODULE_NAME, "收到总召唤确认");
                            break;
                            
                        default:
                            LOG_DEBUG(LOG_MODULE_NAME, "未处理的ASDU类型: %u", asdu.type_id);
                            // 仍然上报原始数据
                            report_raw_asdu_to_mqtt(bridge, &asdu);
                            break;
                    }
                } else {
                    LOG_WARN(LOG_MODULE_NAME, "ASDU解析失败: 错误码=%d", asdu_result);
                }
            }
            
            // 更新统计
            pthread_mutex_lock(&bridge->mutex);
            bridge->stats.iec104_to_mqtt_count++;
            pthread_mutex_unlock(&bridge->mutex);
            
            break;
        }
        
        case APDU_FORMAT_S: {
            // S格式：确认帧
            LOG_DEBUG(LOG_MODULE_NAME, "收到S格式APDU（确认帧）");
            break;
        }
        
        case APDU_FORMAT_U: {
            // U格式：控制帧
            u_format_type_t u_type = (u_format_type_t)apdu.control_field.control1;
            switch (u_type) {
                case U_FORMAT_STARTDT_CON:
                    LOG_INFO(LOG_MODULE_NAME, "收到STARTDT确认");
                    bridge->startdt_activated = true;
                    LOG_DEBUG(LOG_MODULE_NAME, "STARTDT激活状态已设置: startdt_activated=true");
                    LOG_INFO(LOG_MODULE_NAME, "STARTDT激活完成，可以开始数据传输");
                    break;
                case U_FORMAT_STOPDT_CON:
                    LOG_INFO(LOG_MODULE_NAME, "收到STOPDT确认");
                    bridge->startdt_activated = false;  // 停止数据传输时重置激活状态
                    LOG_DEBUG(LOG_MODULE_NAME, "STOPDT确认收到，重置STARTDT激活状态: startdt_activated=false");
                    break;
                case U_FORMAT_TESTFR_CON:
                    LOG_DEBUG(LOG_MODULE_NAME, "收到TESTFR确认");
                    break;
                case U_FORMAT_TESTFR_ACT:
                    LOG_DEBUG(LOG_MODULE_NAME, "收到TESTFR请求，发送确认");
                    // 发送TESTFR确认帧
                    send_testfr_con(bridge);
                    break;
                default:
                    LOG_WARN(LOG_MODULE_NAME, "收到未知U格式类型: 0x%02X", u_type);
                    break;
            }
            break;
        }
        
        default:
            LOG_WARN(LOG_MODULE_NAME, "收到未知APDU格式: %d", format);
            return -1;
    }
    
    return 0;
}

/**
 * @brief 上报数据到MQTT
 */
static int report_data_to_mqtt(iec104_protocol_bridge_t* bridge, const char* data_json) {
    if (bridge->config.mqtt_client == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "MQTT客户端未初始化");
        return -1;
    }
    
    // 检查主题是否配置（mqtt_topic_data是数组，不是指针）
    if (bridge->config.mqtt_topic_data[0] == '\0') {
        // 限制日志频率：1分钟打印一次
        time_t current_time = time(NULL);
        const int error_log_interval = 60;  // 60秒（1分钟）
        
        if (current_time - bridge->last_mqtt_error_log_time >= error_log_interval || 
            bridge->last_mqtt_error_log_time == 0) {
            LOG_WARN(LOG_MODULE_NAME, "数据上报主题未配置，跳过上报（避免连接断开）");
            bridge->last_mqtt_error_log_time = current_time;
        }
        return -1;
    }
    
    // 发布数据到MQTT主题
    mqtt_result_t result = mqtt_client_publish(bridge->config.mqtt_client,
                                               bridge->config.mqtt_topic_data,
                                               (const uint8_t*)data_json,
                                               strlen(data_json),
                                               MQTT_QOS_1,
                                               false);
    
    if (result != MQTT_SUCCESS) {
        // 限制错误日志频率：1分钟打印一次
        time_t current_time = time(NULL);
        const int error_log_interval = 60;  // 60秒（1分钟）
        
        if (current_time - bridge->last_mqtt_error_log_time >= error_log_interval || 
            bridge->last_mqtt_error_log_time == 0) {
            LOG_ERROR(LOG_MODULE_NAME, "发布MQTT消息失败，错误码: %d", result);
            bridge->last_mqtt_error_log_time = current_time;
        }
        return -1;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据已上报到MQTT");
    
    return 0;
}

/**
 * @brief 上报遥信数据到MQTT
 */
static int report_teleindication_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu) {
    if (asdu == NULL) return -1;
    
    cJSON* root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "type", "teleindication");
    cJSON_AddNumberToObject(root, "type_id", asdu->type_id);
    cJSON_AddNumberToObject(root, "common_address", asdu->common_address);
    cJSON_AddNumberToObject(root, "cot", asdu->cause_of_transmission);
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    cJSON_AddNumberToObject(root, "num_objects", asdu->vsq.number_of_objects);
    
    cJSON* points = cJSON_CreateArray();
    
    // 解析信息对象（简化版本）
    const uint8_t* data_ptr = asdu->information_objects;
    size_t bytes_per_object = (asdu->type_id == 1) ? 4 : 5; // 单点4字节，双点5字节
    
    for (int i = 0; i < asdu->vsq.number_of_objects && i < 100; i++) {
        if ((size_t)(data_ptr - asdu->information_objects + bytes_per_object) > asdu->information_objects_length) {
            break;
        }
        
        cJSON* point = cJSON_CreateObject();
        
        // 信息体地址（3字节）
        uint32_t ioa = data_ptr[0] | (data_ptr[1] << 8) | (data_ptr[2] << 16);
        cJSON_AddNumberToObject(point, "address", ioa);
        
        // 单点值（1字节）
        uint8_t value = data_ptr[3];
        cJSON_AddNumberToObject(point, "value", value & 0x01);
        cJSON_AddNumberToObject(point, "quality", (value >> 4) & 0x0F);
        
        cJSON_AddItemToArray(points, point);
        data_ptr += bytes_per_object;
    }
    
    cJSON_AddItemToObject(root, "points", points);
    
    char* json_str = cJSON_PrintUnformatted(root);
    int result = report_data_to_mqtt(bridge, json_str);
    
    cJSON_free(json_str);
    cJSON_Delete(root);
    
    return result;
}

/**
 * @brief 上报遥测数据到MQTT
 */
static int report_telemetry_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu) {
    if (asdu == NULL) return -1;
    
    cJSON* root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "type", "telemetry");
    cJSON_AddNumberToObject(root, "type_id", asdu->type_id);
    cJSON_AddNumberToObject(root, "common_address", asdu->common_address);
    cJSON_AddNumberToObject(root, "cot", asdu->cause_of_transmission);
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    cJSON_AddNumberToObject(root, "num_objects", asdu->vsq.number_of_objects);
    
    cJSON* measurements = cJSON_CreateArray();
    
    // 解析测量值（简化版本）
    const uint8_t* data_ptr = asdu->information_objects;
    size_t bytes_per_object;
    
    switch (asdu->type_id) {
        case 9:  // M_ME_NA_1: 归一化值（2字节值）
            bytes_per_object = 6;  // 3字节地址 + 2字节值 + 1字节质量
            break;
        case 11: // M_ME_NB_1: 标度化值（2字节值）
            bytes_per_object = 6;
            break;
        case 13: // M_ME_NC_1: 短浮点数（4字节值）
            bytes_per_object = 8;  // 3字节地址 + 4字节值 + 1字节质量
            break;
        default:
            bytes_per_object = 8;
            break;
    }
    
    for (int i = 0; i < asdu->vsq.number_of_objects && i < 100; i++) {
        if ((size_t)(data_ptr - asdu->information_objects + bytes_per_object) > asdu->information_objects_length) {
            break;
        }
        
        cJSON* measurement = cJSON_CreateObject();
        
        // 信息体地址（3字节）
        uint32_t ioa = data_ptr[0] | (data_ptr[1] << 8) | (data_ptr[2] << 16);
        cJSON_AddNumberToObject(measurement, "address", ioa);
        
        // 测量值
        if (asdu->type_id == 13) {
            // 短浮点数
            float value;
            memcpy(&value, &data_ptr[3], sizeof(float));
            cJSON_AddNumberToObject(measurement, "value", value);
            cJSON_AddNumberToObject(measurement, "quality", data_ptr[7]);
        } else {
            // 归一化值或标度化值
            int16_t value = (int16_t)(data_ptr[3] | (data_ptr[4] << 8));
            cJSON_AddNumberToObject(measurement, "value", value);
            cJSON_AddNumberToObject(measurement, "quality", data_ptr[5]);
        }
        
        cJSON_AddItemToArray(measurements, measurement);
        data_ptr += bytes_per_object;
    }
    
    cJSON_AddItemToObject(root, "measurements", measurements);
    
    char* json_str = cJSON_PrintUnformatted(root);
    int result = report_data_to_mqtt(bridge, json_str);
    
    cJSON_free(json_str);
    cJSON_Delete(root);
    
    return result;
}

/**
 * @brief 上报原始ASDU数据到MQTT
 */
static int report_raw_asdu_to_mqtt(iec104_protocol_bridge_t* bridge, const asdu_t* asdu) {
    if (asdu == NULL) return -1;
    
    cJSON* root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "type", "raw_asdu");
    cJSON_AddNumberToObject(root, "type_id", asdu->type_id);
    cJSON_AddNumberToObject(root, "common_address", asdu->common_address);
    cJSON_AddNumberToObject(root, "cot", asdu->cause_of_transmission);
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    cJSON_AddNumberToObject(root, "num_objects", asdu->vsq.number_of_objects);
    cJSON_AddNumberToObject(root, "data_length", asdu->information_objects_length);
    
    // 将原始数据转换为十六进制字符串
    char hex_str[512];
    size_t hex_len = 0;
    for (size_t i = 0; i < asdu->information_objects_length && hex_len < sizeof(hex_str) - 3; i++) {
        hex_len += snprintf(hex_str + hex_len, sizeof(hex_str) - hex_len,
                           "%02X", asdu->information_objects[i]);
    }
    cJSON_AddStringToObject(root, "raw_data", hex_str);
    
    char* json_str = cJSON_PrintUnformatted(root);
    int result = report_data_to_mqtt(bridge, json_str);
    
    cJSON_free(json_str);
    cJSON_Delete(root);
    
    LOG_DEBUG(LOG_MODULE_NAME, "上报原始ASDU数据: 类型ID=%u, 长度=%zu",
              asdu->type_id, asdu->information_objects_length);
    
    return result;
}

/**
 * @brief 发送TESTFR确认帧
 */
static int send_testfr_con(iec104_protocol_bridge_t* bridge) {
    if (!bridge->device_connected || bridge->device_socket < 0) {
        LOG_WARN(LOG_MODULE_NAME, "设备未连接，无法发送TESTFR确认");
        return -1;
    }
    
    // U格式TESTFR_CON帧：0x68 0x04 0x83 0x00 0x00 0x00
    uint8_t testfr_con[6] = {
        0x68,  // 启动字符
        0x04,  // 长度（固定4字节）
        0x83,  // 控制域1: TESTFR_CON
        0x00,  // 控制域2
        0x00,  // 控制域3
        0x00   // 控制域4
    };
    
    ssize_t sent = send(bridge->device_socket, testfr_con, sizeof(testfr_con), 0);
    if (sent < 0) {
        LOG_ERROR(LOG_MODULE_NAME, "发送TESTFR确认失败: %s", strerror(errno));
        return -1;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "成功 TESTFR确认已发送: %zd字节", sent);
    
    return 0;
}

/**
 * @brief 发送STARTDT激活帧（启动数据传输）
 */
static int send_startdt_act(iec104_protocol_bridge_t* bridge) {
    if (!bridge->device_connected || bridge->device_socket < 0) {
        LOG_WARN(LOG_MODULE_NAME, "设备未连接，无法发送STARTDT");
        return -1;
    }
    
    // U格式STARTDT_ACT帧：0x68 0x04 0x07 0x00 0x00 0x00
    uint8_t startdt_act[6] = {
        0x68,  // 启动字符
        0x04,  // 长度（固定4字节）
        0x07,  // 控制域1: STARTDT_ACT
        0x00,  // 控制域2
        0x00,  // 控制域3
        0x00   // 控制域4
    };
    
    LOG_DEBUG(LOG_MODULE_NAME, "准备发送STARTDT激活帧: socket=%d, 长度=%zu", 
             bridge->device_socket, sizeof(startdt_act));
    LOG_DEBUG(LOG_MODULE_NAME, "STARTDT激活帧内容: 68 04 07 00 00 00");
    
    ssize_t sent = send(bridge->device_socket, startdt_act, sizeof(startdt_act), 0);
    if (sent < 0) {
        int err = errno;
        LOG_ERROR(LOG_MODULE_NAME, "发送STARTDT激活失败: %s (errno=%d)", strerror(err), err);
        LOG_DEBUG(LOG_MODULE_NAME, "发送失败详情: socket=%d, device_connected=%d", 
                 bridge->device_socket, bridge->device_connected);
        return -1;
    }
    
    if (sent != (ssize_t)sizeof(startdt_act)) {
        LOG_WARN(LOG_MODULE_NAME, "STARTDT激活部分发送: 期望%zu字节，实际%zd字节", 
                sizeof(startdt_act), sent);
    }
    
    LOG_INFO(LOG_MODULE_NAME, "成功 STARTDT激活已发送: %zd字节", sent);
    LOG_DEBUG(LOG_MODULE_NAME, "STARTDT激活发送完成，等待确认");
    
    return 0;
}

